﻿using System;
using System.Management;
using ROOT.CIMV2.Win32;
using System.Windows.Forms;
using System.Net.NetworkInformation;

namespace MassReboot
{
    public class Computer
    {
        public event EventHandler<ComputerEventArgs> RestartStarted;

        public event EventHandler<ComputerEventArgs> ComputerErrorTriggered;

        /// <summary>
        /// Constructor for new computer object
        /// </summary>
        /// <param name="item">List item associated with this Computer object</param>
        /// <param name="forceRestart">Set to true to force this computer to restart without waiting for applications to close.</param>
        /// <param name="username">Username to use when rebooting this computer</param>
        /// <param name="password">Password to use when rebooting a computer</param>
        public Computer(ListViewItem item, bool forceRestart, string username, string password)
        {
            Name = item.SubItems[0].Text;
            Item = item;
            ForceRestart = forceRestart;
            Username = username;
            Password = password;

            using (Ping ping = new Ping())
            {
                try
                {
                    PingReply reply = ping.Send(Name);
                    Addr = reply.Address.ToString();
                }
                catch (Exception ex)
                {
                    Addr = ex.Message;
                }
            }
        }
        public string Username
        {
            get;
            set;
        }

        public string Password
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        public ListViewItem Item
        {
            get;
            set;
        }
        public string Addr
        {
            get;
            set;
        }

        public bool ForceRestart
        {
            get;
            set;
        }
        /// <summary>
        /// Restart this computer
        /// </summary>
        public void BeginRestart()
        {
            try
            {
                OperatingSystem0.StaticScope = new ManagementScope(@"\\" + Name + @"\root\cimv2");

                if (!string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password))
                {
                    OperatingSystem0.StaticScope.Options.Username = Username;
                    OperatingSystem0.StaticScope.Options.Password = Password;
                }

                OperatingSystem0.OperatingSystem0Collection coll = OperatingSystem0.GetInstances();

                string message = "Restarting " + Name;
                foreach (OperatingSystem0 os in coll)
                {
                    if (!os.Path.Server.Equals(Name, StringComparison.CurrentCultureIgnoreCase))
                        {
                            ComputerErrorTriggered(this, new ComputerEventArgs("Found " + os.Path.Server + " when expecting " + Name + " aborting restart.",
                    new string[] { Name, Addr, "Possible DNS issue. Connection returned unexpected system " + os.Path.Server }, ItemStatus.Error));
                            return;  
                      }
                    if (ForceRestart)
                    {
                        
                        //Force Reboot flag = 6
                        os.Win32Shutdown(6, 0);
                    }
                    else
                    {
                        //Reboot normally flag = 2
                        os.Win32Shutdown(2, 0);
                    }
                }
                RestartStarted(this, new ComputerEventArgs(message, new string[] { Name, Addr, " System Restart Initialized" }, ItemStatus.Good));
            }
            catch (Exception ex)
            {
                ComputerErrorTriggered(this, new ComputerEventArgs(Name + " encountered the following error while restarting: " + ex.Message,
                    new string[] { Name, Addr, "Status unknown due to error see log!" }, ItemStatus.Error));
            }
        }
    }
}
